package database.viewer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;

import database.table.DBTableData;

/**
 * @author Hossomi
 *
 */

public class InfoPanel extends JPanel {
	private BufferedImage	image;
	private ImagePanel		imagePanel;
	
	private InfoTableModel	model;
	private JTable			table;

	private ActionListener	control;
	
	public InfoPanel( ActionListener control ) {
		GridBagConstraints constraints = new GridBagConstraints();
		JScrollPane scroll;
		
		setLayout( new GridBagLayout() );
		setBorder(new EmptyBorder(5, 5, 5, 5));
		this.control = control;
		
		constraints.fill = GridBagConstraints.BOTH;
		constraints.gridx = 0;
		constraints.weightx = 1.0;
		
		imagePanel = new ImagePanel();
		new JLabel();
		constraints.gridy = 0;
		constraints.weighty = 3.0;
		add(imagePanel, constraints);
		
		model = new InfoTableModel();
		table = new JTable(model);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		scroll = new JScrollPane(table);

		constraints.gridy = 1;
		constraints.weighty = 1.0;
		add(scroll, constraints);
	}
	
	public int addInfo( String name, Object value ) {
		return model.add(name, value);
	}
	
	public void setInfo( String name, Object value ) {
		model.setValueAt(name, value);
		table.repaint();
	}
	
	public void clearInfo() {
		model.clear();
		table.repaint();
	}
	
	public void setImage( InputStream in ) {
		try {
			image = ImageIO.read(in);
			imagePanel.setImage(image);
			imagePanel.repaint();
		} catch (IOException e) {
			System.out.println("ERROR: could not load image");
		}
	}
	
	public void update( int row, DBTableData data ) {
		if (data == null)
			return;
		
		model.update(row, data);
		table.repaint();
		
		InputStream in = data.getBlobStreamAt(row, "image");
		try {
			image = ImageIO.read(in);
			imagePanel.setImage(image);
			imagePanel.repaint();
		} catch (IOException e) {
			System.out.println("ERROR: could not load image");
		}
	}
	
	private static class InfoTableModel extends AbstractTableModel {
		ArrayList<InfoTableEntry> list;
		
		static final String COL_NAME[] = {"Info", "Value"};
		
		public InfoTableModel() {
			list = new ArrayList<InfoTableEntry>();
		}
		
		public int add( String name, Object value ) {
			list.add( new InfoTableEntry(name, value) );
			return list.size() - 1;
		}
		
		public void clear() {
			list.clear();
		}
		
		@Override
		public int getColumnCount() {
			return COL_NAME.length;
		}

		@Override
		public String getColumnName(int column) {
			return COL_NAME[column];
		}
		
		@Override
		public int getRowCount() {
			return list.size();
		}

		@Override
		public Object getValueAt(int row, int col) {
			try {
				switch (col) {
				case 0: return list.get(row).name;
				case 1: return list.get(row).value;
				}
			}
			catch (IndexOutOfBoundsException e) {
				return null;
			}
			
			return null;
		}
		
		public Object getValueAt( String name ) {
			for (InfoTableEntry e: list) {
				if (e.name.equals(name))
					return e.value;
			}
			
			return null;
		}
		
		@Override
		public void setValueAt(Object value, int row, int col) {
			try {
				switch (col) {
				case 0: list.get(row).name = value.toString(); break;
				case 1: list.get(row).value = value; break;
				}
			}
			catch (IndexOutOfBoundsException e) {
				
			}
		}
		
		public void setValueAt( String name, Object value ) {
			for (InfoTableEntry e: list) {
				if (e.name.equals(name)) {
					e.value = value;
					break;
				}
			}
		}
		
		public void update( int row, DBTableData data ) {
			if (data != null)
				for (InfoTableEntry e: list)
					e.value = data.getValueAt(row, e.name);
		}
	}
	
	private static class InfoTableEntry {
		String name;
		Object value;
		
		public InfoTableEntry( String name, Object value ) {
			this.name = name;
			this.value = value;
		}
	}
}
